package infostroy.bookagolf.views;

import com.academysmart.bookagolf.i18n.Messages;
import com.academysmart.bookagolf.model.Club;
import com.academysmart.bookagolf.model.Image;
import com.academysmart.bookagolf.provider.ClubProvider;
import com.academysmart.bookagolf.provider.ImageProvider;
import infostroy.bookagolf.common.Constants.Colors;
import infostroy.bookagolf.common.Constants.Dimensions;
import infostroy.bookagolf.common.helpers.ImageHelper;
import infostroy.bookagolf.common.helpers.ValidationHelper;
import infostroy.bookagolf.components.controls.GolfRoundButton;
import infostroy.bookagolf.components.dialogs.GolfUploadImgDialog;
import infostroy.bookagolf.components.inputs.GolfComboBox;
import infostroy.bookagolf.components.inputs.GolfDecimalTextField;
import infostroy.bookagolf.components.inputs.GolfSpinner;
import infostroy.bookagolf.components.inputs.GolfTextArea;
import infostroy.bookagolf.components.inputs.GolfTextField;
import infostroy.bookagolf.components.panels.GolfBasePanel;
import infostroy.bookagolf.components.panels.ScrollPanel;
import infostroy.bookagolf.components.widgets.GolfGallery;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;

public class InformationPanel extends GolfBasePanel implements Dimensions, Colors {

    // ---------------------- Constants ------------------------//
    private final static String NAME_LABEL = Messages.CompanyInfo_Name;
    private final static String REGION_LABEL = Messages.CompanyInfo_Region;
    private final static String COUNTRY_LABEL = Messages.CompanyInfo_Country;
    private final static String TOWN_LABEL = Messages.CompanyInfo_City;
    private final static String ADDRESS_LABEL = Messages.CompanyInfo_Address;
    private final static String LATITUDE_LABEL = Messages.CompanyInfo_Latitude;
    private final static String LONGITUDE_LABEL = Messages.CompanyInfo_Longitude;
    private final static String PHONE_LABEL = Messages.CompanyInfo_Phone;
    private final static String EMAIL_LABEL = Messages.CompanyInfo_email;
    private final static String SHORT_DESCRIPTION = Messages.CompanyInfo_ShortDescription;
    private final static String DESCRIPTION = Messages.CompanyInfo_Description;
    private final static String PHOTO_LABEL = Messages.CompanyInfo_Photo;
    private final static String ADD_PHOTO = Messages.CompanyInfo_AddPhoto;
    private final static String HOLES = Messages.CompanyInfo_Holes;
    private final static String PAIRS = Messages.CompanyInfo_Par;
    private final static String SAVE = Messages.CompanyInfo_Save;
    private final static String ADD_PHOTO_DLG = Messages.CompanyInfo_add_photo;


    private JPanel componentsHolder;
    //text inputs
    private JTextField nameJTF = new GolfTextField();
    private JTextField cityJTF = new GolfTextField();
    private JTextField addressJTF = new GolfTextField();
    private JTextField phoneJTF = new GolfTextField();
    private JTextField emailJTF = new GolfTextField();
    //combo boxes
    private JComboBox continentJCB = new GolfComboBox();
    private JComboBox countryJCB = new GolfComboBox();
    //spinners
    private JSpinner latitude = new GolfSpinner();
    private JSpinner longitude = new GolfSpinner();
    //Text labels
    private JLabel nameLbl = new JLabel(NAME_LABEL, SwingConstants.LEFT);
    private JLabel continentLbl = new JLabel(REGION_LABEL);
    private JLabel countryLbl = new JLabel(COUNTRY_LABEL);
    private JLabel cityLbl = new JLabel(TOWN_LABEL);
    private JLabel addressLbl = new JLabel(ADDRESS_LABEL);
    private JLabel latitudeLbl = new JLabel(LATITUDE_LABEL);
    private JLabel longitudeLbl = new JLabel(LONGITUDE_LABEL);
    private JLabel phoneLbl = new JLabel(PHONE_LABEL);
    private JLabel emailLbl = new JLabel(EMAIL_LABEL);

    //text areas
    private JTextArea shortDescriptionJTA = new GolfTextArea();
    private JTextArea descriptionJTA = new GolfTextArea();
    //Text labels
    private JLabel shortDescriptionLbl = new JLabel(SHORT_DESCRIPTION);
    private JLabel descriptionLbl = new JLabel(DESCRIPTION);
    private JLabel holesLbl = new JLabel(HOLES);
    private JLabel pairLbl = new JLabel(PAIRS);
    private JLabel photoLbl = new JLabel(PHOTO_LABEL);
    //Buttons
    private JButton addPhotoBtn = new GolfRoundButton(ADD_PHOTO, BLACK_BUTTON_BACKGROUND
            , BUTTON_FOREGROUND, BLACK_BUTTON_BORDER, ADD_PHOTO_DIM);
    private JComponent saveBtn = new GolfRoundButton(SAVE
            , BLUE_BUTTON_BACKGROUND, BUTTON_FOREGROUND, BLUE_BUTTON_BORDER, BLUE_BUTTON_DIM);
    //Text inputs
    private JTextField holesJCB = new GolfDecimalTextField();
    private JTextField pairJCB = new GolfDecimalTextField();
    //Dialogs
    private GolfUploadImgDialog addPhotoDlg = new GolfUploadImgDialog(ADD_PHOTO_DLG
            , BLACK_BUTTON_BACKGROUND, new Dimension(500, 150), BUTTON_FOREGROUND);
    //Photo gallery
    private GolfGallery gallery = new GolfGallery();
    
    private Club club;

    public InformationPanel() {
        //BorderLayout needed for filling all available space by children
        this.setLayout(new BorderLayout());
        this.setBackground(WHITE);
        //adding padding
        this.setBorder(BorderFactory.createEmptyBorder(15, 0, 15, 15));
        //init container for tab inputs
        this.componentsHolder = new JPanel(new GridLayout(1, 1, 40, 0));
        this.componentsHolder.setBackground(CONTENT_PANEL_BACKGROUND);
        init();        
        this.add(componentsHolder, BorderLayout.CENTER);
        addPhotoDlg.setInformationPanel(this);
    }

    private void init() {
        initLeftPart();
        initRightPart();
        fillInformation();
        disableControls();
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                loadImages();
            }
        });
    }

    private void disableControls() {
        continentJCB.setEnabled(false);
        countryJCB.setEnabled(false);
    }

    private void fillInformation()
    {
    	club = ClubProvider.getClub();
    	if(!ValidationHelper.isNullOrEmpty(club))
    	{
    		nameJTF.setText(club.getName());
    		continentJCB.setSelectedItem(club.getRegion());
    		countryJCB.setSelectedItem(club.getCountry());
    		cityJTF.setText(club.getCity());
    		addressJTF.setText(club.getAddress());
    		longitude.setValue(club.getLng());
    		latitude.setValue(club.getLat());
    		phoneJTF.setText(club.getPhone());
    		emailJTF.setText(club.geteMail());
    		shortDescriptionJTA.setText(club.getShortDescription());
    		descriptionJTA.setText(club.getDescription());
            holesJCB.setText(String.valueOf(club.getHolesList()));
    		pairJCB.setText(String.valueOf(club.getHitsToWin()));
    	}

    }

	public void loadImages() {
		List<com.academysmart.bookagolf.model.Image> clubImages = ImageProvider.INSTANCE
				.getImages();
		for (Image item : clubImages) {
			gallery.addImage(ImageHelper.getInstance().downloadImage(item.getUrl()));
		}
	}

    private void initLeftPart() {
        JPanel leftPanel = new JPanel();
        leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.PAGE_AXIS));
        leftPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 20));
        leftPanel.setBackground(CONTENT_PANEL_BACKGROUND);

        addLabelAndControlH(nameLbl, nameJTF, leftPanel);
        addLabelAndControlH(continentLbl, continentJCB, leftPanel);
        addLabelAndControlH(countryLbl, countryJCB, leftPanel);
        addLabelAndControlH(cityLbl, cityJTF, leftPanel);
        addLabelAndControlH(addressLbl, addressJTF, leftPanel);

        addComponentsToGrid(leftPanel, 1, 2, 10, 0, Box
                .createRigidArea(new Dimension(5, 5)), latitudeLbl, longitudeLbl);
        addComponentsToGrid(leftPanel, 1, 2, 10, 0, Box
                .createRigidArea(new Dimension(5, 10)), latitude, longitude);

        addLabelAndControlH(phoneLbl, phoneJTF, leftPanel);
        addLabelAndControlH(emailLbl, emailJTF, leftPanel);

        componentsHolder.add(leftPanel);
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
	private void initRightPart() {
        JPanel rightPanel = new JPanel();
        rightPanel.setLayout(new BoxLayout(rightPanel, BoxLayout.PAGE_AXIS));
        rightPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 20));
        rightPanel.setBackground(CONTENT_PANEL_BACKGROUND);

        shortDescriptionJTA.setRows(5);
        shortDescriptionJTA.setMaximumSize(shortDescriptionJTA.getMaximumSize());
        JScrollPane pane = new ScrollPanel(shortDescriptionJTA,
                ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        pane.setBorder(null);
        pane.setMaximumSize(shortDescriptionJTA.getMaximumSize());

        descriptionJTA.setRows(5);
        descriptionJTA.setMaximumSize(descriptionJTA.getMaximumSize());
        JScrollPane scrollPane = new ScrollPanel(descriptionJTA,
                ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        scrollPane.setBorder(null);
        scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
        scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        scrollPane.setMaximumSize(descriptionJTA.getMaximumSize());

        addLabelAndControlH(shortDescriptionLbl, pane, rightPanel);
        addLabelAndControlH(descriptionLbl, scrollPane, rightPanel);

        addPhotoBtn.setMaximumSize(new Dimension(125, 25));
        addPhotoBtn.setPreferredSize(new Dimension(125, 25));
        addPhotoBtn.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                addPhotoDlg.setGallery(gallery);
                addPhotoDlg.showDialog();

            }
        });

        addLabelAndControlH(photoLbl, gallery, rightPanel);

        AddInlineComponents(JComponent.LEFT_ALIGNMENT
                , FlowLayout.RIGHT, 0, 0, 35, Box
                .createRigidArea(new Dimension(5, 10)), rightPanel, addPhotoBtn);

        holesJCB.setPreferredSize(new Dimension(60, 30));
        pairJCB.setPreferredSize(new Dimension(60, 30));
        AddInlineComponents(JComponent.LEFT_ALIGNMENT
                , FlowLayout.LEFT, 5, 5, 35, Box
                .createRigidArea(new Dimension(5, 10)), rightPanel, holesLbl, holesJCB, pairLbl, pairJCB);

        saveBtn.setMaximumSize(new Dimension(175, 40));
        saveBtn.setPreferredSize(new Dimension(175, 40));
        saveBtn.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                Club club = ClubProvider.getClub();

                club.setName(nameJTF.getText());
                club.setDescription(descriptionJTA.getText());
                club.setShortDescription(shortDescriptionJTA.getText());
                club.setCity(cityJTF.getText());
                club.setRegion(continentJCB.getSelectedItem().toString());
                club.setCountry(countryJCB.getSelectedItem().toString());
                club.setAddress(addressJTF.getText());
                club.setLat((Double)(latitude.getValue()));
                club.setLng((Double)(longitude.getValue()));
                club.setPhone(phoneJTF.getText());
                club.seteMail(emailJTF.getText());
                club.setHolesList(Integer.parseInt(holesJCB.getText()));
                club.setHitsToWin(Integer.parseInt(pairJCB.getText()));
                ClubProvider.updateClub();
            }
        });
        AddInlineComponents(JComponent.LEFT_ALIGNMENT,
                FlowLayout.RIGHT, 0, 0, 50, Box
                .createRigidArea(new Dimension(5, 10)), rightPanel, saveBtn);

        componentsHolder.add(rightPanel);
    }

    /**
     * Put label over component with left alignment. <code>Container</code>
     * must have <code>BoxLayout</code> with page orientation.
     *
     * @param label     - label of component
     * @param component - text field, combo box and so on.
     * @param container - parent component with BoxLayout.
     */
    private void addLabelAndControlH(JLabel label, JComponent component, JPanel container) {
        label.setAlignmentX(JComponent.LEFT_ALIGNMENT);
        container.add(label);

        container.add(Box.createRigidArea(new Dimension(5, 5)));

        component.setAlignmentX(JComponent.LEFT_ALIGNMENT);
        container.add(component);

        container.add(Box.createRigidArea(new Dimension(5, 10)));
    }

    private void addComponentsToGrid(JPanel container, int rows, int columns
            , int hgap, int vgap, Component rigidArea, JComponent... args) {
        JPanel panel = new JPanel(new GridLayout(rows, columns, hgap, vgap));
        panel.setBackground(new Color(1, 1, 1, 0));
        panel.setAlignmentX(JComponent.LEFT_ALIGNMENT);
        for (JComponent component : args) {
            panel.setMaximumSize(new Dimension(1000
                    , component.getPreferredSize().height));
            panel.add(component);
        }
        container.add(panel);
        container.add(rigidArea);
    }

    private void AddInlineComponents(float panelAlignment, int componentsAlignment,
                                     int hgap, int vgap, int maxHeight, Component rigidArea,
                                     JPanel container, JComponent... args) {
        JPanel panel = new JPanel(new FlowLayout(componentsAlignment, hgap, vgap));
        panel.setMaximumSize(new Dimension(500, maxHeight));
        panel.setBackground(CONTENT_PANEL_BACKGROUND);
        panel.setAlignmentX(panelAlignment);

        for (JComponent component : args) {
            panel.add(component);
        }

        container.add(panel);
        container.add(rigidArea);
    }

    @Override
    public void refreshPanelContent() {
        fillInformation();
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                gallery.cleanImageGallery();
                loadImages();
            }
        });
    }
}

